package au.com.bluelink.scjp.chap8;

public class InnerClassTest {

	public static void main(String[] args) {

		// instantiating an inner Class from Within the outer Class
		MyOuter myOuter = new MyOuter();
		myOuter.makeInner();

		// Creating an inner Class object from outside the outer Class
		// instance Code
		MyOuter mo = new MyOuter(); // gotta get an instance!
		MyOuter.MyInner inner = mo.new MyInner();
		inner.seeOuter();

		// short hand for above method of invocation
		MyOuter.MyInner in = new MyOuter().new MyInner();
		in.seeOuter();

		// referencing the inner or outer instance
		// from Within the inner Class
		MyOuter2.test();
		
		// Method-Local inner Classes
		MyOuter3 myOuter3 = new MyOuter3();
		myOuter3.doStuff();

	}

}

class MyOuter {
	private int x = 7;

	public void makeInner() {
		MyInner in = new MyInner(); // make an inner instance
		in.seeOuter();
	}

	class MyInner {
		public void seeOuter() {
			System.out.println("Outer x is " + x);
		}
	}
}

class MyOuter2 {
	private int x = 7;

	public void makeInner() {
		MyInner in = new MyInner();
		in.seeOuter();
	}

	class MyInner {
		public void seeOuter() {
			System.out.println("Outer x is " + x);
			System.out.println("Inner class ref is " + this);
			System.out.println("Outer class ref is " + MyOuter2.this);
		}
	}

	public static void test() {
		MyOuter2.MyInner inner = new MyOuter2().new MyInner();
		inner.seeOuter();
	}
}

class MyOuter3 {
	private String x = "Outer2";

	void doStuff() {
		class MyInner {
			public void seeOuter() {
				System.out.println("Outer x is " + x);
			} // close inner class method
		} // close inner class definition
		MyInner mi = new MyInner(); // This line must come
		// after the class
		mi.seeOuter();
	} // close outer class method doStuff()
} // close outer class
